#include "registerwin.h"
#include "ui_registerwin.h"
#include <QFileDialog>
#include <QSqlTableModel>
#include <QSqlRecord>
#include <QMessageBox>
#include "randomstring.h"

#include "global_config.h"

RegisterWin::RegisterWin(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::RegisterWin)
{
    ui->setupUi(this);

    sql_op = new SqliteOperator(SERVER_DB_PATH);
    //创建好数据库
    sql_op->open_db();//1.打开数据库
/*
    QString createSql = QString("CREATE TABLE student (\
                          id INT PRIMARY KEY NOT NULL,\
                          name TEXT NOT NULL,\
                          age INT NOT NULL)");*/
    /*
     * if not exisits 应该放在表名之前*/
    /*
    QString create_emptbl_sql = QString("CREATE TABLE IF NOT EXISTS employee  (\
                                        emy_id INT PRIMARY KEY AUTOINCREMENT,\
                                        face_id INT UNIQUE NOT NULL,\
                                        name TEXT NOT NULL,\
                                        sex TEXT NOT NULL,\
                                        part TEXT NOT NULL,\
                                        phone TEXT NOT NULL,\
                                        avatar_path TEXT NOT NULL)");*/
    QString create_emptbl_sql = QString("CREATE TABLE IF NOT EXISTS employee  (\
                                        emy_id INTEGER PRIMARY KEY AUTOINCREMENT,\
                                        face_id INT UNIQUE NOT NULL,\
                                        name varchar(256) NOT NULL,\
                                        sex varchar(32),\
                                        part TEXT,\
                                        phone TEXT,\
                                        avatar_path TEXT)");
    QString create_atdtbl_sql = QString("CREATE TABLE IF NOT EXISTS attendance(\
                                        atd_id integer primary key autoincrement,\
                                        emy_id INT NOT NULL,\
                                        time TimeStamp NOT NULL DEFAULT(datetime('now', 'localtime')))");

    sql_op->create_tbl(create_emptbl_sql);//2. 创建表格：员工表和考勤表
    sql_op->create_tbl(create_atdtbl_sql);

    //检查数据库是否存在
    if(!sql_op->is_tbl_exisit("employee"))
    {
        qDebug()<<"Error:Employee Table do not exisit!";
    }
    else
    {
        qDebug()<<"Employee Table exisit!";
    }

    if(!sql_op->is_tbl_exisit("attendance"))
    {

        qDebug()<<"Error:Attendance Table do not exisit!";
    }
    else
    {
        qDebug()<<"Attendance Table exisit!";
    }

    m_faceop = new FaceObject();
    m_thread = new QThread();

    m_faceop->moveToThread(m_thread);
    m_thread->start();

    //当this发送 ask_register(cv::Mat)信号的时候，m_faceop 执行register的槽；
    //m_faceop 执行register的槽成功之后，产生register_done(const int face_id)信号,this接收,并显示相关信息
    connect(this, &RegisterWin::ask_register, m_faceop,&FaceObject::register_face);
    connect(m_faceop, SIGNAL(register_done(const int)), this, SLOT(get_reg_faceid(const int)));

    m_pictype = BY_FILE;

}

RegisterWin::~RegisterWin()
{
    delete ui;
}

/*
 * @func:resetBtn的SLOT函数
 * @detail:将内容值都清空
*/
void RegisterWin::on_resetBtn_clicked()
{
    ui->nameEdit->clear();
    ui->mRbtn->clearMask();
    ui->fRbtn->clearMask();//必须有一个默认选项，不能清空
    ui->phoneEdit->clear();
    //ui->partBox->clear();//必须有一个默认选项，不能清空

    //其他
    ui->faceidEdit->clear();
}


/*
 * @func:fileBtn 的SLOT函数
 * @detail:弹出文件搜索框，确定文件后，文件名显示在filepathedit上；并且在图片中显示头像
*/
void RegisterWin::on_fileBtn_clicked()
{
    //1. 如何弹出文件搜索框呢？
    QString file_name;
    file_name = QFileDialog::getOpenFileName(this, "文件栏");

    //显示路径
    ui->filepathEdit->setText(file_name);

    //显示图像
    QPixmap avatar(file_name);
    avatar.scaled(254,200);
    avatar = avatar.scaledToWidth(ui->avatarLbl->width());
    ui->avatarLbl->setPixmap(avatar);

    m_pictype = BY_FILE;
}


/*
 * @func:regBtn的SLOT函数
 * @detail:
*/
void RegisterWin::on_regBtn_clicked()
{
    //如果用户是按了文件按键，那么读取路径得到相应的图片；
    //如果用户是拍照，那么通过cv_img来获取图像
    if(m_pictype == BY_FILE)
    {
        ui->avatarLbl->pixmap();
        //0. 得到图片路径
        QString ava_filepath = ui->filepathEdit->text();
        //QPixmap(ava_filepath); register_face 参数类型是cv::Mat
        cv::Mat cv_ava = cv::imread(ava_filepath.toUtf8().data());

        //1. 得到faceid，将相应的图片保存在当下的目录
        //int face_id = m_faceop->register_face(cv_ava);
        emit ask_register(cv_ava);
    }
    else if(m_pictype == BY_CAP)
    {
        emit ask_register(cv_img);
    }
}


/*
 * @func:CapBtn的SLOT函数
*/
void RegisterWin::on_CapBtn_clicked()
{
    if(ui->CapBtn->text()== "摄像头")//打开摄像头动作
    {
        ui->CapBtn->setText("关闭摄像头");
        cap_timer_id = startTimer(200);//200ms一次
        ui->snapBtn->setEnabled(true);//拍照按键使能
    }
    else//关闭摄像头动作
    {
        ui->CapBtn->setText("摄像头");
        killTimer(cap_timer_id);
        ui->snapBtn->setDisabled(true);//拍照按键失能
        cap.release();
    }
}


/*
 * @func:定时器函数：用于读取摄像头数据，并显示图片
*/
void RegisterWin::timerEvent(QTimerEvent *e)
{
    Q_UNUSED(e);
    //cap.open(0);//打开摄像头
    cap.open(0);//打开摄像头

    if(cap.grab())//如果摄像头有数据
    {
        cap.read(cv_img);
    }
    if(cv_img.data == nullptr)//如果图片没得到数据
    {
        return;
    }

    //在label上显示图片
    //显示在屏幕上，将得到的数据做格式转换（从openCV 到 Qt 的格式）
    //1. 转换openCV格式(经过测试不需要转）
    //cvtColor(cv_img, cv_img, cv::COLOR_BGR2RGB);
    //2. cv::Mat 转换为 QImage
    QImage qt_img(cv_img.data, cv_img.cols, cv_img.rows, cv_img.step1(), QImage::Format_RGB888);
    //3. QImage 转换为 QPixmap
    QPixmap qt_map = QPixmap::fromImage(qt_img);
    ui->avatarLbl->setPixmap(qt_map);
}


/*
 * @func:snapBtn 的SLOT函数（进行拍照）
*/
void RegisterWin::on_snapBtn_clicked()
{
    //关闭摄像头
    ui->CapBtn->setText("摄像头");
    killTimer(cap_timer_id);
    ui->snapBtn->setDisabled(true);//拍照按键失能
    cap.release();

    //将得到的图片，保存起来，并设置文件框
    avatar_path = QString("./avatar/%1.jpg").arg(generateRandomString(8));
    //cv::imwrite(filename.toUtf8().data(), cv_img);//如果没有注册成功，那么就没必要保存图像
    ui->filepathEdit->setText(avatar_path);

    m_pictype = BY_CAP;
}


/* SLOT
 * @func:得到注册好的face_id之后，将其他信息一同提交到数据库中
*/
void RegisterWin::get_reg_faceid(const int face_id)
{
    //1. 检查face_id有效性
    qDebug() <<"face_id ==" <<face_id;
    if(face_id < 0)//说明face是无效的
    {
        QMessageBox::information(this, "头像提示","头像识别失败");
        return;//直接返回
    }

    //2. 若face_id有效，则得到其他属性，作为一条记录，插入到表格当中
    QSqlTableModel model;
    model.setTable("employee");
    QSqlRecord rcd = model.record();

    //epy_id 不需要自己设置
    //rcd.setValue("face_id", ui->faceidEdit->text().toInt());//测试face_id（有ui控件）
    rcd.setValue("face_id", face_id);
    rcd.setValue("name",ui->nameEdit->text());
    rcd.setValue("sex", (ui->mRbtn->isChecked())?"男":"女");
    rcd.setValue("part", ui->partBox->currentText());
    rcd.setValue("phone", ui->phoneEdit->text());
    rcd.setValue("avatar_path", ui->filepathEdit->text());

    if(m_pictype == BY_CAP)
    {
        cv::imwrite(avatar_path.toUtf8().data(), cv_img);//通过摄像头注册成功，保存当前的头像
    }
    else//通过文件注册成功
    {

    }

    bool ret = model.insertRecord(0,rcd);//0代表第0行
    if(ret)
    {
        QMessageBox::information(this, "注册提示","注册成功");
        //提交
        model.submitAll();
    }
    else
    {
        QMessageBox::information(this, "注册提示","注册失败");
    }

#if 0
    epyRcd reg_rcd;
    reg_rcd.m_epyID = ui->idEdit->text().toInt();//我希望员工序号自动生成，不需要自己在界面设置获取
    reg_rcd.m_faceID =ui->faceidEdit->text().toInt();

    reg_rcd.m_name =  ui->nameEdit->text();
    //1. 取得数据:包括姓名、性别等等
    reg_rcd.m_sex = (ui->mRbtn->isChecked())?"男":"女";
    reg_rcd.m_part = ui->partBox->currentText();
    reg_rcd.m_phone = ui->phoneEdit->text();
    //1-x 特殊的数据：人脸的缩略图（头像）的路径
    //QString filepath = ui->filepathEdit->text();

    //2. 将数据传入数据库中
    sql_op->single_insert_data(reg_rcd);
#endif
}
